/**
 * 控制器的实现，主要是渲染图形界面
 * controller.c
 */

#include "controller.h"

GtkBuilder *builder;


void app_run()
{
	GObject *window;
	GObject *load;
	GObject *save;
	GObject *about;
	GObject *insert_club;
	GObject *insert_player;
	GObject *insert_game;
	GObject *query_club_by_name;
	GObject *query_club_by_coach;
	GObject *show_clubs;
	GObject *query_player_by_name;
	GObject *query_player_by_club_and_victories;
	GObject *query_player_by_clubname;
	GObject *query_game_by_id_and_player;
	GObject *query_game_by_player_and_status;
	GObject *query_game_by_clubname_and_player;
	GObject *update_coach;
	GObject *update_rank;
	GObject *update_game;
	GObject *delete_club;
	GObject *delete_player;
	GObject *delete_game;
	GObject *club_ranking;
	GObject *player_ranking;
	GObject *rank_sum;
	GObject *rank_ranking;
	GObject *club_info;
	GObject *show_all;

	builder = gtk_builder_new();
	gtk_builder_add_from_file(builder, "loms.ui", NULL);

	window = gtk_builder_get_object(builder, "window1");
	g_signal_connect(window, "delete-event", 
		G_CALLBACK(run_quit_dialog), NULL);
	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

	load = gtk_builder_get_object(builder, "imagemenuitem1");
	g_signal_connect(load, "activate", G_CALLBACK(run_load), NULL);

	save = gtk_builder_get_object(builder, "imagemenuitem2");
	g_signal_connect(save, "activate", G_CALLBACK(run_save), NULL);

	about = gtk_builder_get_object(builder, "imagemenuitem10");
	g_signal_connect(about, "activate", 
		G_CALLBACK(run_about_dialog), NULL);

	insert_club = gtk_builder_get_object(builder, "imagemenuitem6");
	g_signal_connect(insert_club, "activate", 
		G_CALLBACK(run_insert_club), NULL);

	insert_player = gtk_builder_get_object(builder, "imagemenuitem7");
	g_signal_connect(insert_player, "activate", 
		G_CALLBACK(run_insert_player), NULL);

	insert_game = gtk_builder_get_object(builder, "imagemenuitem8");
	g_signal_connect(insert_game, "activate", 
		G_CALLBACK(run_insert_game), NULL);

	query_club_by_name = gtk_builder_get_object(builder, "menuitem6");
	g_signal_connect(query_club_by_name, "activate",
		G_CALLBACK(run_query_club_by_substring), NULL);

	query_club_by_coach = gtk_builder_get_object(builder, "menuitem7");
	g_signal_connect(query_club_by_coach, "activate",
		G_CALLBACK(run_query_club_by_coach), NULL);

	show_clubs = gtk_builder_get_object(builder, "menuitem15");
	g_signal_connect(show_clubs, "activate", 
		G_CALLBACK(run_show_clubs), NULL);

	query_player_by_name = gtk_builder_get_object(builder, "menuitem9");
	g_signal_connect(query_player_by_name, "activate",
		G_CALLBACK(run_query_player_by_name), NULL);

	query_player_by_club_and_victories = gtk_builder_get_object(builder, "menuitem11");
	g_signal_connect(query_player_by_club_and_victories, "activate",
		G_CALLBACK(run_query_player_by_club_and_victories), NULL);

	query_player_by_clubname = gtk_builder_get_object(builder, "menuitem19");
	g_signal_connect(query_player_by_clubname, "activate",
		G_CALLBACK(run_query_player_by_clubname), NULL);

	query_game_by_id_and_player = gtk_builder_get_object(builder, "menuitem13");
	g_signal_connect(query_game_by_id_and_player, "activate",
		G_CALLBACK(run_query_game_by_id_and_player), NULL);

	query_game_by_player_and_status = gtk_builder_get_object(builder, "menuitem14");
	g_signal_connect(query_game_by_player_and_status, "activate",
		G_CALLBACK(run_query_game_by_player_and_status), NULL);

	query_game_by_clubname_and_player = gtk_builder_get_object(builder, "menuitem31");
	g_signal_connect(query_game_by_clubname_and_player, "activate",
		G_CALLBACK(run_query_game_by_clubname_and_player), NULL);

	update_coach = gtk_builder_get_object(builder, "menuitem17");
	g_signal_connect(update_coach, "activate",
		G_CALLBACK(run_update_coach), NULL);

	update_rank = gtk_builder_get_object(builder, "menuitem20");
	g_signal_connect(update_rank, "activate",
		G_CALLBACK(run_update_rank), NULL);

	update_game = gtk_builder_get_object(builder, "menuitem21");
	g_signal_connect(update_game, "activate",
		G_CALLBACK(run_update_game), NULL);

	delete_club = gtk_builder_get_object(builder, "menuitem23");
	g_signal_connect(delete_club, "activate",
		G_CALLBACK(run_delete_club), NULL);

	delete_player = gtk_builder_get_object(builder, "imagemenuitem3");
	g_signal_connect(delete_player, "activate",
		G_CALLBACK(run_delete_player), NULL);

	delete_game = gtk_builder_get_object(builder, "menuitem24");
	g_signal_connect(delete_game, "activate", 
		G_CALLBACK(run_delete_game), NULL);

	club_ranking = gtk_builder_get_object(builder, "menuitem26");
	g_signal_connect(club_ranking, "activate",
		G_CALLBACK(run_club_ranking), NULL);

	player_ranking = gtk_builder_get_object(builder, "menuitem27");
	g_signal_connect(player_ranking, "activate", 
		G_CALLBACK(run_player_ranking), NULL);

	rank_sum = gtk_builder_get_object(builder, "menuitem28");
	g_signal_connect(rank_sum, "activate",
		G_CALLBACK(run_rank_sum), NULL);

	rank_ranking = gtk_builder_get_object(builder, "menuitem10");
	g_signal_connect(rank_ranking, "activate",
		G_CALLBACK(run_rank_ranking), NULL);

	club_info = gtk_builder_get_object(builder, "menuitem29");
	g_signal_connect(club_info, "activate",
		G_CALLBACK(run_club_info), NULL);

	show_all = gtk_builder_get_object(builder, "menuitem30");
	g_signal_connect(show_all, "activate",
		G_CALLBACK(run_show_all), NULL);


	return;
}


void run_load(GtkWidget *widget, gpointer data)
{
	load();
	return;
}


void run_save(GtkWidget *widget, gpointer data)
{
	save();
	return;
}


void run_about_dialog(GtkWidget *widget, gpointer data)
{
	GObject *dialog = gtk_builder_get_object(builder, "aboutdialog1");
	
	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	gtk_widget_hide(GTK_WIDGET(dialog));

	return;
}


void run_insert_club(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, clubname long = -3, coach long, exist = -1, null} flag;
	int flag = 1;
	while(run_insert_club_with_input(&flag) != 2);
	return;
}


int run_insert_club_with_input(int *flag)
{
	GObject *dialog;
	GObject *button;
	GObject *label1;
	GObject *label2;
	GObject *label3;
	GObject *input1;
	GObject *input2;
	char clubname[CLUBNAME_LEN];
	char coach[PERSON_LEN];

	dialog = gtk_builder_get_object(builder, "dialog2");
	label1 = gtk_builder_get_object(builder, "label5");
	label2 = gtk_builder_get_object(builder, "label6"); 
	label3 = gtk_builder_get_object(builder, "label7");
	input1 = gtk_builder_get_object(builder, "entry4");
	input2 = gtk_builder_get_object(builder, "entry5");

	gtk_label_set_text(GTK_LABEL(label1), "俱乐部");
	gtk_label_set_text(GTK_LABEL(label2), "教练");
	gtk_entry_set_max_length(GTK_ENTRY(input1), 18);
	gtk_entry_set_placeholder_text(GTK_ENTRY(input1), "不超过18字节");
	gtk_entry_set_max_length(GTK_ENTRY(input2), 9);
	gtk_entry_set_placeholder_text(GTK_ENTRY(input2), "不超过9字节");

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label3), "俱乐部或教练信息为空!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label3), "记录已存在!");
			break;

		case -2:
			gtk_label_set_text(GTK_LABEL(label3), "教练名称过长!");
			break;

		case -3:
			gtk_label_set_text(GTK_LABEL(label3), "俱乐部名称过长!");
			break;

		default:
			gtk_entry_set_text(GTK_ENTRY(input1), "");
			gtk_entry_set_text(GTK_ENTRY(input2), "");
			gtk_label_set_text(GTK_LABEL(label3), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			// strcpy(clubname, gtk_entry_get_text(GTK_ENTRY(input1)));
			// strcpy(coach, gtk_entry_get_text(GTK_ENTRY(input2)));
			// debug("%s %s", clubname, coach);
			// debug("clubname_length:%d\ncoach_lenth:%d",
				// strlen(clubname), strlen(coach));
			if (strlen(gtk_entry_get_text(GTK_ENTRY(input1))) &&
			    strlen(gtk_entry_get_text(GTK_ENTRY(input2))))
			{
				if(strlen(gtk_entry_get_text(GTK_ENTRY(input1))) > 18)
				{
					*flag = -3;
				}
				else if (strlen(gtk_entry_get_text(GTK_ENTRY(input2))) > 9)
				{
					*flag = -2;
				}
				else if(query_club_by_name(gtk_entry_get_text(GTK_ENTRY(input1))) || 
				query_club_by_coach(gtk_entry_get_text(GTK_ENTRY(input2))))
				{
					*flag = -1;
				}
				else
				{
					*flag = 2;
					insert_club(gtk_entry_get_text(GTK_ENTRY(input1)),
								 gtk_entry_get_text(GTK_ENTRY(input2)));	
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}	
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_insert_player(GtkWidget *widget, gpointer data)
{
	// enum{start = 1, success, player long = -3, no_club, exist, null} flag;
	int flag = 1;
	while(run_insert_player_with_input(&flag) != 2);
	return;
}


int run_insert_player_with_input(int *flag)
{
	GtkDialog *dialog = GTK_DIALOG(gtk_builder_get_object(builder, "dialog4"));
	GtkLabel *label = GTK_LABEL(gtk_builder_get_object(builder, "label14"));
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext21");
	GtkEntry *entry2 = GTK_ENTRY(gtk_builder_get_object(builder, "entry8"));
	GObject *combo = gtk_builder_get_object(builder, "comboboxtext1");

	char clubname[CLUBNAME_LEN];
	char player[PERSON_LEN];
	char rank_str[2];
	char rank;
	Club *pc;

	gtk_combo_box_text_remove_all(combo_club);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_club, pc -> name);
	}

	switch(*flag)
	{
		case -3:
			gtk_label_set_text(label, "棋手姓名过长!");
			break;

		case -2:
			gtk_label_set_text(label, "俱乐部信息有误!");
			break;

		case -1:
			gtk_label_set_text(label, "记录已存在!");
			break;

		case 0:
			gtk_label_set_text(label, "请填写完整信息,不能留空!");
			break;

		default:
			gtk_entry_set_text(entry2, "");
			gtk_label_set_text(label, "");
	}

	gint result = gtk_dialog_run(dialog);

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			strcpy(player, gtk_entry_get_text(entry2));
			strcpy(rank_str, gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo));
			rank = rank_str[0];
			if (gtk_combo_box_text_get_active_text(combo_club) &&
				 strlen(player) && strlen(rank_str))
			{
				strcpy(clubname, gtk_combo_box_text_get_active_text(combo_club));
				if (strlen(player) > 9)
				{
					*flag = -3;
				}
				else if (query_club_by_name(clubname))
				{
					if(query_player_by_name(clubname, player))
					{
						//record exists
						*flag = -1;
					}
					else
					{
						//success
						insert_player(clubname, player, rank);
						*flag = 2;
					}
				}
				else
				{
					//club not exists
					*flag = -2;
				}
			}
			else
			{
				//infomation missing
				*flag = 0;
			}
			break;
	}

	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_insert_game(GtkWidget *widget, gpointer data)
{
	// enum{start = 1, success, conflict = -2, exist = -1, null} flag;
	int flag = 1;
	while(run_insert_game_with_input(&flag) != 2);
	return;
}


int run_insert_game_with_input(int *flag)
{
	GtkDialog *dialog = GTK_DIALOG(gtk_builder_get_object(builder, "dialog5"));
	GtkLabel *label_info = GTK_LABEL(gtk_builder_get_object(builder, "label22"));
	GObject *combo_id = gtk_builder_get_object(builder, "comboboxtext2");
	GObject *combo_tag = gtk_builder_get_object(builder, "comboboxtext3");
	GObject *combo_blackteam = gtk_builder_get_object(builder, "comboboxtext4");
	GObject *combo_whiteteam = gtk_builder_get_object(builder, "comboboxtext5");
	GObject *combo_black = gtk_builder_get_object(builder, "comboboxtext6");
	GObject *combo_white = gtk_builder_get_object(builder, "comboboxtext7");
	GObject *combo_status = gtk_builder_get_object(builder, "comboboxtext8");
	gulong signal_id[2];

	int id;
	char tag;
	char tag_str[20];
	char blackteam[CLUBNAME_LEN];
	char whiteteam[CLUBNAME_LEN];
	char black[PERSON_LEN];
	char white[PERSON_LEN];
	char status;
	char status_str[20];
	Club *pc;
	Player *pp;
	Player *p1;
	Player *p2;

	gtk_combo_box_text_remove_all((GtkComboBoxText *)combo_blackteam);
	gtk_combo_box_text_remove_all((GtkComboBoxText *)combo_whiteteam);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text((GtkComboBoxText *)combo_blackteam, pc -> name);
		gtk_combo_box_text_append_text((GtkComboBoxText *)combo_whiteteam, pc -> name);
	}
	signal_id[0] = g_signal_connect(combo_blackteam, "changed", G_CALLBACK(call_player_data_black), combo_blackteam);
	signal_id[1] = g_signal_connect(combo_whiteteam, "changed", G_CALLBACK(call_player_data_white), combo_whiteteam);
	
	switch(*flag)
	{
		case 0:
			gtk_label_set_text(label_info, "请填写完整信息,不能留空!");
			break;

		case -1:
			gtk_label_set_text(label_info, "操作失败,记录已存在或矛盾!");
			break;

		case -2:
			gtk_label_set_text(label_info, "黑方白方相同!");
			break;

		default:
			gtk_label_set_text(label_info, "");
	}

	gint result = gtk_dialog_run(dialog);

	switch(result)
	{
		case 1:
			debug("press cancle!");
			//success
			*flag = 2;
			break;

		case 2:
			if (gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_blackteam) &&
				gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_whiteteam) &&
				gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_black) &&
				gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_white))
			{
				id = atoi(gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_id));
				strcpy(tag_str, gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_tag));
				strcpy(blackteam, gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_blackteam));
				strcpy(whiteteam, gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_whiteteam));
				strcpy(black, gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_black));
				strcpy(white, gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_white));
				strcpy(status_str, gtk_combo_box_text_get_active_text((GtkComboBoxText *)combo_status));
	
				if (!strcmp(tag_str, "主将局"))
				{
					tag = '0';
				}
				else
				{
					tag = strcmp(tag_str, "快棋局") ? '2' : '1';
				}
				status = strcmp(status_str, "黑胜") ? '1' : '0';
				if (check_game(blackteam, id, black, tag) || 
					check_game(whiteteam, id, white, tag))
				{
					//exist
					*flag = -1;
				}
				else if(!strcmp(blackteam, whiteteam))
				{
					//conflict
					*flag = -2; 
				}
				else
				{
					p1 = query_player_by_name(blackteam, black);
					p2 = query_player_by_name(whiteteam, white);
					insert_game(id, tag, blackteam, whiteteam, black, white, status, p1);
					insert_game(id, tag, blackteam, whiteteam, black, white, status, p2);
					//success
					*flag = 2;
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}

	g_signal_handler_disconnect(combo_blackteam, signal_id[0]);
	g_signal_handler_disconnect(combo_whiteteam, signal_id[1]);
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void call_player_data_black(GtkComboBoxText *widget, GObject *combo, gpointer data)
{
	GObject *combo_to = gtk_builder_get_object(builder, "comboboxtext6");

	call_player_data((GtkComboBoxText *)combo, (GtkComboBoxText *)combo_to);

	return;
}


void call_player_data_white(GtkComboBoxText *widget, GObject *combo, gpointer data)
{
	GObject *combo_to = gtk_builder_get_object(builder, "comboboxtext7");

	call_player_data((GtkComboBoxText *)combo, (GtkComboBoxText *)combo_to);

	return;
}


void call_player_data(GtkComboBoxText *combo_from, GtkComboBoxText *combo_to)
{
	Club *pc;
	Player *pp;
	char clubname[CLUBNAME_LEN];

	debug("233");
	strcpy(clubname, gtk_combo_box_text_get_active_text(combo_from));
	debug("%s", clubname);
	gtk_combo_box_text_remove_all(combo_to);

	pc = query_club_by_name(clubname);
	for(pp = pc -> player; pp; pp = pp -> next)
	{
		gtk_combo_box_text_append_text(combo_to, pp -> name);
	}

	return;
}


/**
 * fill data for treeview of club
 * @param data  data
 * @param mode  'a': show all; 'n': by keyword of name; 'c': by keword of coach
 */
static void fill_data_query_club(const char *data, char mode)
{
	enum{
		COL_CLUB = 0,
		COL_COACH,
		COL_SITEPOINT,
		COL_GAMEPOINT,
		NUM_COLS
	};
	
	GtkCellRenderer *renderer;
	GtkTreeModel *model;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;

	Club *pc;

	// view = gtk_tree_view_new();
	view = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));

	GList *list;
	GList *l;
	list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
	for(l = list; l; l = l -> next)
	{
		gtk_tree_view_remove_column(GTK_TREE_VIEW(view), l -> data);
	}
	g_list_free(list);
	
	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "俱乐部",  
                                               renderer,
                                               "text", COL_CLUB,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "教练",  
                                               renderer,
                                               "text", COL_COACH,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "场分",  
                                               renderer,
                                               "text", COL_SITEPOINT,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "局分",  
                                               renderer,
                                               "text", COL_GAMEPOINT,
                                               NULL);

	store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);

	switch(mode)
	{
		case 'a':
			for(pc = head; pc; pc = pc -> next)
			{
				gtk_list_store_append (store, &iter);
				gtk_list_store_set (store, &iter,
		                      COL_CLUB, pc -> name,
		                      COL_COACH, pc -> coach,
		                      COL_SITEPOINT, pc -> sitepoint,
		                      COL_GAMEPOINT, pc -> gamepoint,
		                      -1);	  
			}
			break;

		case 'n':
			for(pc = head; pc; pc = pc -> next)
			{
				if(strstr(pc -> name, data) != NULL)
				{
					gtk_list_store_append (store, &iter);
					gtk_list_store_set (store, &iter,
			                      COL_CLUB, pc -> name,
			                      COL_COACH, pc -> coach,
			                      COL_SITEPOINT, pc -> sitepoint,
			                      COL_GAMEPOINT, pc -> gamepoint,
			                      -1);
				}
			}
			break;

		case 'c':
			for(pc = head; pc; pc = pc -> next)
			{
				if(strstr(pc -> coach, data) != NULL)
				{
					gtk_list_store_append (store, &iter);
					gtk_list_store_set (store, &iter,
			                      COL_CLUB, pc -> name,
			                      COL_COACH, pc -> coach,
			                      COL_SITEPOINT, pc -> sitepoint,
			                      COL_GAMEPOINT, pc -> gamepoint,
			                      -1);
				}
			}
			break;
	}

	model = GTK_TREE_MODEL(store);
	gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
	g_object_unref (model);

	GtkBox *box = GTK_BOX(gtk_builder_get_object(builder, "box1"));
	gtk_box_pack_end(box, view, TRUE, TRUE, 0);
	
	gtk_widget_show(view);
}


void run_query_club_by_substring(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, too long = -2, not exist, null} flag;
	int flag = 1;
	while(run_query_club_by_substring_loop(&flag) != 2);
	return;
}


int run_query_club_by_substring_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog1");
	GObject *label_key = gtk_builder_get_object(builder, "label8");
	GObject *entry_key = gtk_builder_get_object(builder, "entry6");
	GObject *label_info = gtk_builder_get_object(builder, "label9");
	GObject *button_cancle = gtk_builder_get_object(builder, "button7");
	GObject *button_ok = gtk_builder_get_object(builder, "button8");

	char keyword[CLUBNAME_LEN];

	gtk_label_set_text(GTK_LABEL(label_key), "关键字");
	gtk_entry_set_max_length(GTK_ENTRY(entry_key), 18);
	gtk_entry_set_placeholder_text(GTK_ENTRY(entry_key), "不超过18字节");

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "关键字为空!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_entry_set_text(GTK_ENTRY(entry_key), "");
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			strcpy(keyword, gtk_entry_get_text(GTK_ENTRY(entry_key)));
			debug("keyword: %s", keyword);
			if (strlen(keyword))
			{
				if (strlen(keyword) > 18)
				{
					//too long
					*flag = -2;
				}
				else if(!query_club_by_substring(keyword))
				{
					//not exist
					*flag = -1;
				}
				else
				{
					//success
					*flag = 2;
					fill_data_query_club(keyword, 'n');
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}	
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;

}


void run_query_club_by_coach(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -1, null} flag;
	int flag = 1;
	while(run_query_club_by_coach_loop(&flag) != 2);
	return;
}


int run_query_club_by_coach_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog1");
	GObject *label_key = gtk_builder_get_object(builder, "label8");
	GObject *entry_key = gtk_builder_get_object(builder, "entry6");
	GObject *label_info = gtk_builder_get_object(builder, "label9");
	GObject *button_cancle = gtk_builder_get_object(builder, "button7");
	GObject *button_ok = gtk_builder_get_object(builder, "button8");

	char keyword[CLUBNAME_LEN];

	gtk_label_set_text(GTK_LABEL(label_key), "关键字");
	gtk_entry_set_max_length(GTK_ENTRY(entry_key), 9);
	gtk_entry_set_placeholder_text(GTK_ENTRY(entry_key), "不超过9字节");

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "关键字为空!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_entry_set_text(GTK_ENTRY(entry_key), "");
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			strcpy(keyword, gtk_entry_get_text(GTK_ENTRY(entry_key)));
			debug("keyword: %s", keyword);
			if (strlen(keyword))
			{
				if(!query_club_by_coach_substr(keyword))
				{
					//not exist
					*flag = -1;
				}
				else
				{
					//success
					*flag = 2;
					fill_data_query_club(keyword, 'c');
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}	
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;

}


/**
 * use when having label in the main window
 * @param widget [description]
 * @param data   [description]
 */
// void run_show_clubs(GtkWidget *widget, gpointer data)
// {
// 	GtkLabel *label_info = GTK_LABEL(gtk_builder_get_object(builder, "label1"));

// 	int length_sum = 0;

// 	Club *pc;
// 	Label *str = NULL;
// 	Label *pl;
// 	char *label_str;

// 	for(pc = head; pc; pc = pc -> next)
// 	{
// 		pl = str;
// 		str = (Label *)malloc(sizeof(Label));
// 		sprintf(str -> str, "%-CLUBNAME_LENs %-PERSON_LENs %-3d %-3d\n",
// 			pc -> name, pc -> coach, pc -> sitepoint, pc -> gamepoint);
// 		str -> next = pl;
// 	}
// 	pl = str;
// 	str = (Label *)malloc(sizeof(Label));
// 	sprintf(str -> str, "%s\t\t%s\t\t%s\t\t%s\n", "俱乐部", "教练", "场分", "局分");
// 	str -> next = pl;
	
// 	for(pl = str; pl; pl = pl -> next)
// 	{
// 		length_sum += strlen(pl -> str);
// 	}
// 	length_sum ++;
// 	label_str = (char *)malloc(length_sum * sizeof(char));
// 	strcpy(label_str, "");
// 	for(pl = str; pl; pl = pl -> next)
// 	{
// 		strcat(label_str, pl -> str);
// 	}

// 	gtk_label_set_text(label_info, label_str);

// 	return;
// }


static void fill_data_query_player(const char *data, const int v, char mode)
{
	enum{
		COL_PLAYER = 0,
		COL_CLUB,
		COL_COACH,
		COL_RANK,
		COL_GAMESUM,
		COL_VICTORIES,
		NUM_COLS
	};
	
	GtkCellRenderer *renderer;
	GtkTreeModel *model;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;

	Club *pc;
	Player *pp;

	// view = gtk_tree_view_new();
	view = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));
	
	GList *list;
	GList *l;
	list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
	for(l = list; l; l = l -> next)
	{
		gtk_tree_view_remove_column(GTK_TREE_VIEW(view), l -> data);
	}
	g_list_free(list);
	
	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "棋手",  
                                               renderer,
                                               "text", COL_PLAYER,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "所属俱乐部",  
                                               renderer,
                                               "text", COL_CLUB,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "教练",  
                                               renderer,
                                               "text", COL_COACH,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "段位",  
                                               renderer,
                                               "text", COL_RANK,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "参赛局数",  
                                               renderer,
                                               "text", COL_GAMESUM,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "胜局数",  
                                               renderer,
                                               "text", COL_VICTORIES,
                                               NULL);

	store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, 
		G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);

	switch(mode)
	{
		case 'n':
			for(pc = head; pc; pc = pc -> next)
			{
				for(pp = pc -> player; pp; pp = pp -> next)
				{
					if(!strcmp(pp -> name, data))
					{
						gtk_list_store_append (store, &iter);
						gtk_list_store_set (store, &iter,
			                      COL_PLAYER, pp -> name,
			                      COL_CLUB, pp -> clubname,
			                      COL_COACH, pp -> club -> coach,
			                      COL_RANK, pp -> rank - '0',
			                      COL_GAMESUM, pp -> gamesum,
			                      COL_VICTORIES, pp -> victories,
			                      -1);
					}
				}
			}
			break;

		case 'v':
			pc = query_club_by_name(data);
			for(pp = pc -> player; pp; pp = pp -> next)
			{
				if(pp -> victories == v)
				{
					gtk_list_store_append (store, &iter);
					gtk_list_store_set (store, &iter,
		                      COL_PLAYER, pp -> name,
		                      COL_CLUB, pp -> clubname,
		                      COL_COACH, pp -> club -> coach,
		                      COL_RANK, pp -> rank -'0',
		                      COL_GAMESUM, pp -> gamesum,
		                      COL_VICTORIES, pp -> victories,
		                      -1);
				}
			}
			break;

		case 'a':
			pc = query_club_by_name(data);
			if(pc)
			{
				debug("%s", pc -> name);
			}
			else
			{
				debug("not exist!");
			}
			for(pp = pc -> player; pp; pp = pp -> next)
			{
				gtk_list_store_append (store, &iter);
				gtk_list_store_set (store, &iter,
	                      COL_PLAYER, pp -> name,
	                      COL_CLUB, pp -> clubname,
	                      COL_COACH, pp -> club -> coach,
	                      COL_RANK, pp -> rank -'0',
	                      COL_GAMESUM, pp -> gamesum,
	                      COL_VICTORIES, pp -> victories,
	                      -1);
			}
			break;
	}

	model = GTK_TREE_MODEL(store);
	gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
	g_object_unref (model);

	GtkBox *box = GTK_BOX(gtk_builder_get_object(builder, "box1"));
	gtk_box_pack_end(box, view, TRUE, TRUE, 0);

	gtk_widget_show(view);
}


void run_query_player_by_name(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -1, null} flag;
	int flag = 1;
	while(run_query_player_by_name_loop(&flag) != 2);
	return;
}


int run_query_player_by_name_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog1");
	GObject *label_key = gtk_builder_get_object(builder, "label8");
	GObject *entry_key = gtk_builder_get_object(builder, "entry6");
	GObject *label_info = gtk_builder_get_object(builder, "label9");
	GObject *button_cancle = gtk_builder_get_object(builder, "button7");
	GObject *button_ok = gtk_builder_get_object(builder, "button8");

	char keyword[PERSON_LEN];

	gtk_label_set_text(GTK_LABEL(label_key), "关键字");
	gtk_entry_set_max_length(GTK_ENTRY(entry_key), 9);
	gtk_entry_set_placeholder_text(GTK_ENTRY(entry_key), "不超过9字节");

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "关键字为空!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_entry_set_text(GTK_ENTRY(entry_key), "");
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			strcpy(keyword, gtk_entry_get_text(GTK_ENTRY(entry_key)));
			debug("keyword: %s", keyword);
			if (strlen(keyword))
			{
				if(!query_player_by_name_only(keyword))
				{
					//not exist
					*flag = -1;
				}
				else
				{
					//success
					*flag = 2;
					fill_data_query_player(keyword, 0, 'n');
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}	
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_query_player_by_club_and_victories(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -1, null} flag;
	int flag = 1;
	while(run_query_player_by_club_and_victories_loop(&flag) != 2);
	return;
}


// int run_query_player_by_club_and_victories_loop(int *flag)
// {
// 	GObject *dialog = gtk_builder_get_object(builder, "dialog2");
// 	GObject *label_club = gtk_builder_get_object(builder, "label5");
// 	GObject *label_victories = gtk_builder_get_object(builder, "label6");
// 	GObject *entry_club = gtk_builder_get_object(builder, "entry4");
// 	GObject *entry_victories = gtk_builder_get_object(builder, "entry5");
// 	GObject *label_info = gtk_builder_get_object(builder, "label9");
// 	GObject *button_cancle = gtk_builder_get_object(builder, "button7");
// 	GObject *button_ok = gtk_builder_get_object(builder, "button8");

// 	char clubname[CLUBNAME_LEN];
// 	char victories_str[5];
// 	int victories;

// 	gtk_label_set_text(GTK_LABEL(label_club), "俱乐部");
// 	gtk_entry_set_max_length(GTK_ENTRY(entry_club), 14);
// 	gtk_entry_set_placeholder_text(GTK_ENTRY(entry_club), "不超过14字节");

// 	gtk_label_set_text(GTK_LABEL(label_victories), "胜局数");
// 	gtk_entry_set_placeholder_text(GTK_ENTRY(entry_victories), "胜局数");


// 	switch (*flag)
// 	{
// 		case 0:
// 			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
// 			break;

// 		case -1:
// 			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
// 			break;

// 		default:
// 			gtk_entry_set_text(GTK_ENTRY(entry_club), "");
// 			gtk_entry_set_text(GTK_ENTRY(entry_victories), "");
// 			gtk_label_set_text(GTK_LABEL(label_info), "");
// 	}

// 	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

// 	switch(result)
// 	{
// 		case 1:
// 			debug("press cancle!");
// 			*flag = 2;
// 			break;

// 		case 2:
// 			debug("press ok!");
// 			strcpy(clubname, gtk_entry_get_text(GTK_ENTRY(entry_club)));
// 			strcpy(victories_str, gtk_entry_get_text(GTK_ENTRY(entry_victories)));
// 			if (strlen(clubname) && strlen(victories_str))
// 			{
// 				victories = atoi(victories_str);
// 				if(!query_player_by_club_and_victories(clubname, victories))
// 				{
// 					//not exist
// 					*flag = -1;
// 				}
// 				else
// 				{
// 					//success
// 					*flag = 2;
// 					fill_data_query_player(clubname, victories, 'v');
// 				}
// 			}
// 			else
// 			{
// 				*flag = 0;
// 			}
// 			break;
// 	}
	
// 	gtk_widget_hide(GTK_WIDGET(dialog));

// 	return *flag;
// }
int run_query_player_by_club_and_victories_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog8");
	GtkLabel *label_victories = (GtkLabel *)gtk_builder_get_object(builder, "label29");
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext11");
	GtkEntry *entry_victories = (GtkEntry *)gtk_builder_get_object(builder, "entry11");
	GObject *label_info = gtk_builder_get_object(builder, "label30");
	GObject *button_cancle = gtk_builder_get_object(builder, "button17");
	GObject *button_ok = gtk_builder_get_object(builder, "button18");

	char clubname[CLUBNAME_LEN];
	char victories_str[5];
	int victories;
	Club *pc;

	gtk_label_set_text(GTK_LABEL(label_victories), "胜局数");
	gtk_entry_set_placeholder_text(GTK_ENTRY(entry_victories), "胜局数");

	gtk_combo_box_text_remove_all(combo_club);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_club, pc -> name);
	}

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_entry_set_text(GTK_ENTRY(entry_victories), "");
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			strcpy(victories_str, gtk_entry_get_text(GTK_ENTRY(entry_victories)));
			if (gtk_combo_box_text_get_active_text(combo_club) && strlen(victories_str))
			{
				strcpy(clubname, gtk_combo_box_text_get_active_text(combo_club));
				victories = atoi(victories_str);
				if(!query_player_by_club_and_victories(clubname, victories))
				{
					//not exist
					*flag = -1;
				}
				else
				{
					//success
					*flag = 2;
					pc = query_club_by_name(clubname);
					if (!(pc -> player))
					{
						run_warning_dialog();
					}
					else
					{
						fill_data_query_player(clubname, victories, 'v');
					}

				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_query_player_by_clubname(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, no records = -1, null = 0} flag;
	int flag = 1;
	while(run_query_player_by_clubname_loop(&flag) != 2);
	return;
}


static int run_query_player_by_clubname_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog11");
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext20");
	GObject *label_info = gtk_builder_get_object(builder, "label42");
	
	Club *pc;
	char clubname[CLUBNAME_LEN];

	gtk_combo_box_text_remove_all(combo_club);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_club, pc -> name);
	}
	
	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "记录不存在!");
			break;

		default:
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			if (gtk_combo_box_text_get_active_text(combo_club))
			{
				strcpy(clubname, gtk_combo_box_text_get_active_text(combo_club));
				pc = query_club_by_name(clubname);
				if(!(pc -> player))
				{
					*flag = -1;
				}
				else
				{
					*flag = 2;
					fill_data_query_player(clubname, 0, 'a');
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


static void fill_data_query_game(const char *data, const char *clubname, const int arg, char mode)
{
	enum{
		COL_ID = 0,
		COL_PLAYER,
		COL_TAG,
		COL_BLACK,
		COL_WHITE,
		COL_BLACKTEAM,
		COL_WHITETEAM,
		COL_STATUS,
		NUM_COLS
	};
	
	GtkCellRenderer *renderer;
	GtkTreeModel *model;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;

	Club *pc;
	Player *pp;
	Game *pg;
	char tag[PERSON_LEN];
	char status[PERSON_LEN];
	char id_str[5];

	// view = gtk_tree_view_new();
	view = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));
	
	GList *list;
	GList *l;
	list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
	for(l = list; l; l = l -> next)
	{
		gtk_tree_view_remove_column(GTK_TREE_VIEW(view), l -> data);
	}
	g_list_free(list);
	
	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,   
                                               "场次",  
                                               renderer,
                                               "text", COL_ID,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "棋手",  
                                               renderer,
                                               "text", COL_PLAYER,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "局别",  
                                               renderer,
                                               "text", COL_TAG,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "黑手",  
                                               renderer,
                                               "text", COL_BLACK,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "白手",  
                                               renderer,
                                               "text", COL_WHITE,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "黑方",  
                                               renderer,
                                               "text", COL_BLACKTEAM,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "白方",  
                                               renderer,
                                               "text", COL_WHITETEAM,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "胜负",  
                                               renderer,
                                               "text", COL_STATUS,
                                               NULL);

	store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, 
		G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);

	switch(mode)
	{
		case 'i':
			for(pc = head; pc; pc = pc -> next)
			{
				for(pp = pc -> player; pp; pp = pp -> next)
				{
					if(!strcmp(pp -> name, data))
					{
						for(pg = pp -> game; pg; pg = pg -> next)
						{
							if (pg -> id == arg)
							{
								strcpy(tag, tag_to_string(pg -> tag));
								strcpy(status, status_to_string(pg -> status));
								sprintf(id_str, "%d", pg -> id);
								gtk_list_store_append(store, &iter);
								gtk_list_store_set(store, &iter,
									COL_ID, id_str,
									COL_PLAYER, pg -> player -> name,
									COL_TAG, tag,
									COL_BLACK, pg -> black,
									COL_WHITE, pg -> white,
									COL_BLACKTEAM, pg -> blackteam,
									COL_WHITETEAM, pg -> whiteteam,
									COL_STATUS, status);
							}
						}
					}
				}
			}
			break;

		case 's':
			for(pc = head; pc; pc = pc -> next)
			{
				for(pp = pc -> player; pp; pp = pp -> next)
				{
					if(!strcmp(pp -> name, data))
					{
						for(pg = pp -> game; pg; pg = pg -> next)
						{
							if (arg)
							{
								if (get_winner(pg -> player -> name,
									   pg -> black, pg -> white, pg -> status))
								{
									strcpy(tag, tag_to_string(pg -> tag));
									strcpy(status, status_to_string(pg -> status));
									sprintf(id_str, "%d", pg -> id);
									gtk_list_store_append(store, &iter);
									gtk_list_store_set(store, &iter,
										COL_ID, id_str,
										COL_PLAYER, pg -> player -> name,
										COL_TAG, tag,
										COL_BLACK, pg -> black,
										COL_WHITE, pg -> white,
										COL_BLACKTEAM, pg -> blackteam,
										COL_WHITETEAM, pg -> whiteteam,
										COL_STATUS, status);
								}	
							}
							else
							{
								if (!get_winner(pg -> player -> name,
									   pg -> black, pg -> white, pg -> status))
								{
									debug("get lose game");
									strcpy(tag, tag_to_string(pg -> tag));
									strcpy(status, status_to_string(pg -> status));
									sprintf(id_str, "%d", pg -> id);
									gtk_list_store_append(store, &iter);
									gtk_list_store_set(store, &iter,
										COL_ID, id_str,
										COL_PLAYER, pg -> player -> name,
										COL_TAG, tag,
										COL_BLACK, pg -> black,
										COL_WHITE, pg -> white,
										COL_BLACKTEAM, pg -> blackteam,
										COL_WHITETEAM, pg -> whiteteam,
										COL_STATUS, status);
								}	
							}
						}
					}
				}
			}
			break;

		case 'n':
			pp = query_player_by_name(clubname, data);
			for(pg = pp -> game; pg; pg = pg -> next)
			{
				debug("pg -> id: %d", pg -> id);
				sprintf(id_str, "%d", pg -> id);
				debug("Tran: pg -> id: %s", id_str);
				strcpy(tag, tag_to_string(pg -> tag));
				strcpy(status, status_to_string(pg -> status));
				gtk_list_store_append(store, &iter);
				gtk_list_store_set(store, &iter,
					COL_ID, id_str,
					COL_PLAYER, pg -> player -> name,
					COL_TAG, tag,
					COL_BLACK, pg -> black,
					COL_WHITE, pg -> white,
					COL_BLACKTEAM, pg -> blackteam,
					COL_WHITETEAM, pg -> whiteteam,
					COL_STATUS, status);
				debug("After pg -> id: %d", pg -> id);
			}
			break;
	}

	model = GTK_TREE_MODEL(store);
	gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
	g_object_unref (model);

	GtkBox *box = GTK_BOX(gtk_builder_get_object(builder, "box1"));
	gtk_box_pack_end(box, view, TRUE, TRUE, 0);

	gtk_widget_show(view);
}


void run_query_game_by_id_and_player(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -1, null} flag;
	int flag = 1;
	while(run_query_game_by_id_and_player_loop(&flag) != 2);
	return;
}


int run_query_game_by_id_and_player_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog6");
	GtkComboBoxText *combo_id = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext9");
	GObject *entry_player = gtk_builder_get_object(builder, "entry9");
	GObject *label_info = gtk_builder_get_object(builder, "label24");
	GObject *button_cancle = gtk_builder_get_object(builder, "button13");
	GObject *button_ok = gtk_builder_get_object(builder, "button14");

	int id;
	char player[PERSON_LEN];

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_entry_set_text(GTK_ENTRY(entry_player), "");
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			strcpy(player, gtk_entry_get_text(GTK_ENTRY(entry_player)));
			if (strlen(player))
			{
				id = atoi(gtk_combo_box_text_get_active_text(combo_id));
				if(!query_game_by_id_and_player(id, player))
				{
					//not exist
					*flag = -1;
				}
				else
				{
					//success
					*flag = 2;
					fill_data_query_game(player, "", id, 'i');
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_query_game_by_player_and_status(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -1, null} flag;
	int flag = 1;
	while(run_query_game_by_player_and_status_loop(&flag) != 2);
	return;
}


int run_query_game_by_player_and_status_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog7");
	GtkComboBoxText *combo_status = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext10");
	GObject *entry_player = gtk_builder_get_object(builder, "entry10");
	GObject *label_info = gtk_builder_get_object(builder, "label27");
	GObject *button_cancle = gtk_builder_get_object(builder, "button15");
	GObject *button_ok = gtk_builder_get_object(builder, "button16");

	char status_str[PERSON_LEN];
	char player[PERSON_LEN];

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_entry_set_text(GTK_ENTRY(entry_player), "");
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			strcpy(player, gtk_entry_get_text(GTK_ENTRY(entry_player)));
			if (strlen(player))
			{
				strcpy(status_str, gtk_combo_box_text_get_active_text(combo_status));
				if (!strcmp(status_str, "胜"))
				{
					debug("win");
					if (!query_game_by_status(player, 1))
					{
						//not exist
						*flag = -1;
					}
					else
					{
						//success
						*flag = 2;
						fill_data_query_game(player, "", 1, 's');
					}
				}
				else
				{
					debug("lose");
					if (!query_game_by_status(player, 0))
					{
						debug("not exist!");
						//not exist
						*flag = -1;
					}
					else
					{
						debug("success");
						//success
						*flag = 2;
						fill_data_query_game(player, "", 0, 's');
					}
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_query_game_by_clubname_and_player(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exists = -1, null} flag;
	int flag = 1;
	while(run_query_game_by_clubname_and_player_loop(&flag) != 2);
	return;
}


static int run_query_game_by_clubname_and_player_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog9");
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext12");
	GtkComboBoxText *combo_player = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext13");
	GtkComboBoxText *combo_rank = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext14");
	GObject *label_rank = gtk_builder_get_object(builder, "label33");
	GObject *label_info = gtk_builder_get_object(builder, "label34");
	gulong signal_id;

	Club *pc;
	Player *pp;
	char clubname[CLUBNAME_LEN];
	char player[PERSON_LEN];

	gtk_widget_hide((GtkWidget *)combo_rank);
	gtk_widget_hide((GtkWidget *)label_rank);

	gtk_combo_box_text_remove_all(combo_club);
	gtk_combo_box_text_remove_all(combo_player);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_club, pc -> name);
	}
	signal_id = g_signal_connect(combo_club, "changed", G_CALLBACK(call_player_data_for_update), NULL);

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			if (gtk_combo_box_text_get_active_text(combo_club) &&
				gtk_combo_box_text_get_active_text(combo_player))
			{
				strcpy(clubname, gtk_combo_box_text_get_active_text(combo_club));
				strcpy(player, gtk_combo_box_text_get_active_text(combo_player));
				pp = query_player_by_name(clubname, player);
				if (!(pp -> game))
				{
					//not exist
					*flag = -1;
				}
				else
				{
					//success
					*flag = 2;
					fill_data_query_game(player, clubname, 0, 'n');
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	

	g_signal_handler_disconnect(combo_club, signal_id);
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_update_coach(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -1, null} flag;
	int flag = 1;
	while(run_update_coach_loop(&flag) != 2);
	return;
}


int run_update_coach_loop(int *flag)
{

	GObject *dialog = gtk_builder_get_object(builder, "dialog8");
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext11");
	GtkLabel *label_coach = GTK_LABEL(gtk_builder_get_object(builder, "label29"));
	GObject *entry_coach = gtk_builder_get_object(builder, "entry11");
	GObject *label_info = gtk_builder_get_object(builder, "label30");
	GObject *button_cancle = gtk_builder_get_object(builder, "button17");
	GObject *button_ok = gtk_builder_get_object(builder, "button18");

	Club *pc;
	char coach[PERSON_LEN];

	gtk_label_set_text(label_coach, "新教练");
	gtk_entry_set_placeholder_text(GTK_ENTRY(entry_coach), "新教练");

	gtk_combo_box_text_remove_all(combo_club);

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_entry_set_text(GTK_ENTRY(entry_coach), "");
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_club, pc -> name);
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			strcpy(coach, gtk_entry_get_text(GTK_ENTRY(entry_coach)));
			if (strlen(coach) && gtk_combo_box_text_get_active_text(combo_club))
			{
				pc = query_club_by_name(gtk_combo_box_text_get_active_text(combo_club));
				if(!pc)
				{
					//not exist
					*flag = -1;
				}
				else
				{
					//success
					*flag = 2;
					strcpy(pc -> coach, coach);
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_update_rank(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -1, null} flag;
	int flag = 1;
	while(run_update_rank_loop(&flag) != 2);
	return;
}


int run_update_rank_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog9");
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext12");
	GtkComboBoxText *combo_player = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext13");
	GtkComboBoxText *combo_rank = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext14");
	GObject *label_info = gtk_builder_get_object(builder, "label34");
	GtkLabel *label_club = GTK_LABEL(gtk_builder_get_object(builder, "label31"));
	GtkLabel *label_player = GTK_LABEL(gtk_builder_get_object(builder, "label32"));
	GtkLabel *label_rank = GTK_LABEL(gtk_builder_get_object(builder, "label33"));
	GObject *button_cancle = gtk_builder_get_object(builder, "button19");
	GObject *button_ok = gtk_builder_get_object(builder, "button20");
	gulong signal_id;

	Club *pc;
	Player *pp;
	char rank_str[5];

	gtk_label_set_text(label_club, "俱乐部");
	gtk_label_set_text(label_player, "棋手");
	gtk_label_set_text(label_rank, "段位");

	gtk_combo_box_text_remove_all(combo_club);
	gtk_combo_box_text_remove_all(combo_player);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_club, pc -> name);
	}
	signal_id = g_signal_connect(combo_club, "changed", G_CALLBACK(call_player_data_for_update), NULL);

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			if (gtk_combo_box_text_get_active_text(combo_club) &&
				gtk_combo_box_text_get_active_text(combo_player))
			{
				strcpy(rank_str, gtk_combo_box_text_get_active_text(combo_rank));
				pp = query_player_by_name(gtk_combo_box_text_get_active_text(combo_club), 
									gtk_combo_box_text_get_active_text(combo_player));
				//success
				*flag = 2;
				pp -> rank = rank_str[0];
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	

	g_signal_handler_disconnect(combo_club, signal_id);
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


static void call_player_data_for_update(GtkWidget *widget, gpointer data)
{
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext12");
	GtkComboBoxText *combo_player = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext13");

	call_player_data(combo_club, combo_player);
}


void run_update_game(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -2, conflict = -1, null} flag;
	int flag = 1;
	while(run_update_game_loop(&flag) != 2);
	return;
}


static void insert_game_for_update()
{
	// enum{start = 1, success, conflict = -2, exist = -1, null} flag;
	int flag = 1;
	while(run_insert_game_with_input(&flag) != 2);
	return;
}


static int run_update_game_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog10");
	GtkComboBoxText *combo_id = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext15");
	GtkComboBoxText *combo_blackteam = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext16");
	GtkComboBoxText *combo_whiteteam = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext17");
	GtkComboBoxText *combo_black = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext18");
	GtkComboBoxText *combo_white = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext19");
	GObject *label_info = gtk_builder_get_object(builder, "label40");
	GObject *button_cancle = gtk_builder_get_object(builder, "button21");
	GObject *button_ok = gtk_builder_get_object(builder, "button22");
	gulong signal_id[2];

	Club *pc;
	Player *pp;
	char id_str[3];
	char blackteam[CLUBNAME_LEN];
	char whiteteam[CLUBNAME_LEN];
	char black[PERSON_LEN];
	char white[PERSON_LEN];
	int id;

	gtk_combo_box_text_remove_all(combo_blackteam);
	gtk_combo_box_text_remove_all(combo_whiteteam);
	gtk_combo_box_text_remove_all(combo_black);
	gtk_combo_box_text_remove_all(combo_white);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_blackteam, pc -> name);
		gtk_combo_box_text_append_text(combo_whiteteam, pc -> name);
	}
	signal_id[0] = g_signal_connect(combo_blackteam, "changed", G_CALLBACK(call_player_data_for_update_black), NULL);
	signal_id[1] = g_signal_connect(combo_whiteteam, "changed", G_CALLBACK(call_player_data_for_update_white), NULL);
	
	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "矛盾!");
			break;

		case -2:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			if (gtk_combo_box_text_get_active_text(combo_black) &&
				gtk_combo_box_text_get_active_text(combo_white) &&
				gtk_combo_box_text_get_active_text(combo_id))
			{
				strcpy(id_str, gtk_combo_box_text_get_active_text(combo_id));
				strcpy(blackteam, gtk_combo_box_text_get_active_text(combo_blackteam));
				strcpy(whiteteam, gtk_combo_box_text_get_active_text(combo_whiteteam));
				strcpy(black, gtk_combo_box_text_get_active_text(combo_black));
				strcpy(white, gtk_combo_box_text_get_active_text(combo_white));
				id = atoi(id_str);
				if(!strcmp(blackteam, whiteteam))
				{
					*flag = -1;
				}
				else
				{
					if (!query_game_before_delete(id, blackteam, whiteteam, black, white))
					{
						//not exist
						*flag = -2;
					}
					else
					{
						//success
						*flag = 2;
						delete_game(id, blackteam, whiteteam, black, white);
						insert_game_for_update();
					}
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	

	g_signal_handler_disconnect(combo_blackteam, signal_id[0]);
	g_signal_handler_disconnect(combo_whiteteam, signal_id[1]);
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


static void call_player_data_for_update_black(GtkWidget *widget, gpointer data)
{
	GtkComboBoxText *combo_blackteam = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext16");
	GtkComboBoxText *combo_black = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext18");

	call_player_data(combo_blackteam, combo_black);
}


static void call_player_data_for_update_white(GtkWidget *widget, gpointer data)
{
	GtkComboBoxText *combo_whiteteam = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext17");
	GtkComboBoxText *combo_white = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext19");

	call_player_data(combo_whiteteam, combo_white);
}


void run_delete_club(GtkWidget *widget, gpointer data)
{
	// enum{start = 1, success, null} flag;
	int flag = 1;
	while(run_delete_club_loop(&flag) != 2);
	return;
}


static int run_delete_club_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog11");
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext20");
	GObject *label_info = gtk_builder_get_object(builder, "label42");
	GObject *button_cancle = gtk_builder_get_object(builder, "button21");
	GObject *button_ok = gtk_builder_get_object(builder, "button22");
	
	Club *pc;

	gtk_combo_box_text_remove_all(combo_club);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_club, pc -> name);
	}
	
	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		default:
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			if (gtk_combo_box_text_get_active_text(combo_club))
			{
				*flag = 2;
				delete_club(gtk_combo_box_text_get_active_text(combo_club));
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_delete_player(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, null} flag;
	int flag = 1;
	while(run_delete_player_loop(&flag) != 2);
	return;
}


static int run_delete_player_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog9");
	GtkComboBoxText *combo_club = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext12");
	GtkComboBoxText *combo_player = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext13");
	GtkComboBoxText *combo_rank = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext14");
	GObject *label_rank = gtk_builder_get_object(builder, "label33");
	GObject *label_info = gtk_builder_get_object(builder, "label34");
	GObject *button_cancle = gtk_builder_get_object(builder, "button19");
	GObject *button_ok = gtk_builder_get_object(builder, "button20");
	gulong signal_id;

	Club *pc;

	gtk_widget_hide((GtkWidget *)combo_rank);
	gtk_widget_hide((GtkWidget *)label_rank);

	gtk_combo_box_text_remove_all(combo_club);
	gtk_combo_box_text_remove_all(combo_player);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_club, pc -> name);
	}
	signal_id = g_signal_connect(combo_club, "changed", G_CALLBACK(call_player_data_for_update), NULL);

	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		default:
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			if (gtk_combo_box_text_get_active_text(combo_club) &&
				gtk_combo_box_text_get_active_text(combo_player))
			{
				//success
				*flag = 2;
				delete_player(gtk_combo_box_text_get_active_text(combo_club), 
									gtk_combo_box_text_get_active_text(combo_player));
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	

	g_signal_handler_disconnect(combo_club, signal_id);
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


void run_delete_game(GtkWidget *widget, gpointer data)
{
	// enum {start = 1, success, not exist = -2, conflict = -1, null} flag;
	int flag = 1;
	while(run_delete_game_loop(&flag) != 2);
	return;
}


static int run_delete_game_loop(int *flag)
{
	GObject *dialog = gtk_builder_get_object(builder, "dialog10");
	GtkComboBoxText *combo_id = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext15");
	GtkComboBoxText *combo_blackteam = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext16");
	GtkComboBoxText *combo_whiteteam = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext17");
	GtkComboBoxText *combo_black = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext18");
	GtkComboBoxText *combo_white = (GtkComboBoxText *)gtk_builder_get_object(builder, "comboboxtext19");
	GObject *label_info = gtk_builder_get_object(builder, "label40");
	GObject *button_cancle = gtk_builder_get_object(builder, "button21");
	GObject *button_ok = gtk_builder_get_object(builder, "button22");
	gulong signal_id[2];

	Club *pc;
	Player *pp;
	char id_str[3];
	char blackteam[CLUBNAME_LEN];
	char whiteteam[CLUBNAME_LEN];
	char black[PERSON_LEN];
	char white[PERSON_LEN];
	int id;

	gtk_combo_box_text_remove_all(combo_blackteam);
	gtk_combo_box_text_remove_all(combo_whiteteam);
	gtk_combo_box_text_remove_all(combo_black);
	gtk_combo_box_text_remove_all(combo_white);
	for(pc = head; pc; pc = pc -> next)
	{
		gtk_combo_box_text_append_text(combo_blackteam, pc -> name);
		gtk_combo_box_text_append_text(combo_whiteteam, pc -> name);
	}
	signal_id[0] = g_signal_connect(combo_blackteam, "changed", G_CALLBACK(call_player_data_for_update_black), NULL);
	signal_id[1] = g_signal_connect(combo_whiteteam, "changed", G_CALLBACK(call_player_data_for_update_white), NULL);
	
	switch (*flag)
	{
		case 0:
			gtk_label_set_text(GTK_LABEL(label_info), "信息缺失!");
			break;

		case -1:
			gtk_label_set_text(GTK_LABEL(label_info), "矛盾!");
			break;

		case -2:
			gtk_label_set_text(GTK_LABEL(label_info), "不存在相关记录!");
			break;

		default:
			gtk_label_set_text(GTK_LABEL(label_info), "");
	}

	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			*flag = 2;
			break;

		case 2:
			debug("press ok!");
			if (gtk_combo_box_text_get_active_text(combo_black) &&
				gtk_combo_box_text_get_active_text(combo_white) &&
				gtk_combo_box_text_get_active_text(combo_id))
			{
				strcpy(id_str, gtk_combo_box_text_get_active_text(combo_id));
				strcpy(blackteam, gtk_combo_box_text_get_active_text(combo_blackteam));
				strcpy(whiteteam, gtk_combo_box_text_get_active_text(combo_whiteteam));
				strcpy(black, gtk_combo_box_text_get_active_text(combo_black));
				strcpy(white, gtk_combo_box_text_get_active_text(combo_white));
				id = atoi(id_str);
				if(!strcmp(blackteam, whiteteam))
				{
					*flag = -1;
				}
				else
				{
					if (!query_game_before_delete(id, blackteam, whiteteam, black, white))
					{
						//not exist
						*flag = -2;
					}
					else
					{
						//success
						*flag = 2;
						delete_game(id, blackteam, whiteteam, black, white);
					}
				}
			}
			else
			{
				*flag = 0;
			}
			break;
	}
	

	g_signal_handler_disconnect(combo_blackteam, signal_id[0]);
	g_signal_handler_disconnect(combo_whiteteam, signal_id[1]);
	gtk_widget_hide(GTK_WIDGET(dialog));

	return *flag;
}


static int check_before_ranking()
{
	Club *pc;
	Player *pp;
	Game *pg;
	int flag_found = 0;

	for(pc = head; pc; pc = pc -> next)
	{
		for(pp = pc -> player; pp; pp = pp -> next)
		{
			return 2;
		}
		flag_found = 1;
	}

	return flag_found;
}


static void run_warning_dialog()
{
	GObject *dialog = gtk_builder_get_object(builder, "messagedialog3");

	gtk_dialog_run(GTK_DIALOG(dialog));

	gtk_widget_hide(GTK_WIDGET(dialog));

}


void run_club_ranking(GtkWidget *widget, gpointer data)
{
	if(!check_before_ranking())
	{
		run_warning_dialog();
		return;
	}

	enum{
		COL_CLUB = 0,
		COL_COACH,
		COL_SITEPOINT,
		COL_GAMEPOINT,
		COL_WIN,
		COL_LOSE,
		NUM_COLS
	};
	
	GtkCellRenderer *renderer;
	GtkTreeModel *model;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;

	Tcr *pt_head = NULL;
	Tcr *pt;

	view = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));

	GList *list;
	GList *l;
	list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
	for(l = list; l; l = l -> next)
	{
		gtk_tree_view_remove_column(GTK_TREE_VIEW(view), l -> data);
	}
	g_list_free(list);
	
	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "俱乐部",  
                                               renderer,
                                               "text", COL_CLUB,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "教练",  
                                               renderer,
                                               "text", COL_COACH,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "场分",  
                                               renderer,
                                               "text", COL_SITEPOINT,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "局分",  
                                               renderer,
                                               "text", COL_GAMEPOINT,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "胜局数",  
                                               renderer,
                                               "text", COL_WIN,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "负局数",  
                                               renderer,
                                               "text", COL_LOSE,
                                               NULL);

	store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT,
		G_TYPE_INT, G_TYPE_INT);

	club_ranking(&pt_head);
	for(pt = pt_head; pt; pt = pt -> next)
	{
		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
	                  COL_CLUB, pt -> clubname,
	                  COL_COACH, pt -> coach,
	                  COL_SITEPOINT, pt -> sitepoint,
	                  COL_GAMEPOINT, pt -> gamepoint,
	                  COL_WIN, pt -> win,
	                  COL_LOSE, pt -> lose,
	                  -1);
	}

	model = GTK_TREE_MODEL(store);
	gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
	g_object_unref (model);

	GtkBox *box = GTK_BOX(gtk_builder_get_object(builder, "box1"));
	gtk_box_pack_end(box, view, TRUE, TRUE, 0);
	
	gtk_widget_show(view);
	free(pt_head);
	pt_head = NULL;
}


static void club_ranking(Tcr **pt_head)
{
	// typedef struct temp
	// {
	// 	char clubname[CLUBNAME_LEN];
	// 	char coach[PERSON_LEN];
	// 	int sitepoint;
	// 	int gamepoint;
	// 	int win;
	// 	int lose;
	// 	struct temp *next;
	// }Temp;

	Rank *pr;
	Club *pc;
	Player *pp;
	Game *pg;
	Tcr *pt;
	Tcr *p1;
	Tcr *p2;
	Tcr *t;
	Tcr *prior1;
	Tcr *prior2;
	int win;
	int lose;
	
	// if (head == NULL)
	// {
	// 	printf("no records!\n");
	// 	return;
	// }
	for(pc = head; pc; pc = pc -> next)
	{
		pt = *pt_head;
		*pt_head = (Tcr *)malloc(sizeof(Tcr));
		strcpy((*pt_head) -> clubname, pc -> name);
		strcpy((*pt_head) -> coach, pc -> coach);
		(*pt_head) -> sitepoint = pc -> sitepoint;
		(*pt_head) -> gamepoint = pc -> gamepoint;
		win = lose = 0;
		for(pp = pc -> player; pp; pp = pp -> next)
		{
			for(pg = pp -> game; pg; pg = pg -> next)
			{
				if (get_winner(pp -> name, pg -> black,
					pg -> white, pg -> status))
				{
					win ++;
				}
				else
				{
					lose ++;
				}
			}
		}
		(*pt_head) -> win = win;
		(*pt_head) -> lose = lose;
		(*pt_head) -> next = pt;
	}
	p1 = (Tcr *)malloc(sizeof(Tcr));
	p1 -> next = *pt_head;
	*pt_head = p1;
	for(prior1 = p1, p1 = prior1 -> next; p1 -> next; prior1 = p1, p1 = p1 -> next)
	{
		for(prior2 = p1, p2 = prior2 -> next; p2; prior2 = p2, p2 = p2 -> next)
		{
			if (p1 -> sitepoint < p2 -> sitepoint ||
				((p1 -> sitepoint == p2 -> sitepoint) &&
					(p1 -> gamepoint < p2 -> gamepoint)))
			{
				t = p2 -> next;
				prior1 -> next = p2;
				prior2 -> next = p1;
				p2 -> next = p1 -> next;
				p1 -> next = t;
				t = p1;
				p1 = p2;
				p2 = p1;
			}
		}	
	}
	p1 = *pt_head;
	*pt_head = p1 -> next;
	free(p1);
	p1 = NULL;

	return;
}


void run_player_ranking(GtkWidget *widget, gpointer data)
{
	if(check_before_ranking() != 2)
	{
		run_warning_dialog();
		return;
	}

	enum{
		COL_PLAYER = 0,
		COL_CLUB,
		COL_GAMESUM,
		COL_WIN,
		COL_LOSE,
		COL_RATE,
		NUM_COLS
	};
	
	GtkCellRenderer *renderer;
	GtkTreeModel *model;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;

	Tpr *pt_head = NULL;
	Tpr *pt;

	view = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));

	GList *list;
	GList *l;
	list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
	for(l = list; l; l = l -> next)
	{
		gtk_tree_view_remove_column(GTK_TREE_VIEW(view), l -> data);
	}
	g_list_free(list);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "棋手",  
                                               renderer,
                                               "text", COL_PLAYER,
                                               NULL);
	
	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "俱乐部",  
                                               renderer,
                                               "text", COL_CLUB,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "参赛局数",  
                                               renderer,
                                               "text", COL_GAMESUM,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "胜局数",  
                                               renderer,
                                               "text", COL_WIN,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "负局数",  
                                               renderer,
                                               "text", COL_LOSE,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "胜率",  
                                               renderer,
                                               "text", COL_RATE,
                                               NULL);

	store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT,
		G_TYPE_INT, G_TYPE_FLOAT);

	player_ranking(&pt_head);
	for(pt = pt_head; pt; pt = pt -> next)
	{
		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
	                  COL_PLAYER, pt -> player,
	                  COL_CLUB, pt -> clubname,
	                  COL_GAMESUM, pt -> gamesum,
	                  COL_WIN, pt -> win,
	                  COL_LOSE, pt -> lose,
	                  COL_RATE, pt -> rate,
	                  -1);
	}

	model = GTK_TREE_MODEL(store);
	gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
	g_object_unref (model);

	GtkBox *box = GTK_BOX(gtk_builder_get_object(builder, "box1"));
	gtk_box_pack_end(box, view, TRUE, TRUE, 0);
	
	gtk_widget_show(view);
	free(pt_head);
	pt_head = NULL;
}


static void player_ranking(Tpr **pt_head)
{

	Club *pc;
	Player *pp;
	Game *pg;
	Tpr *pt;
	Tpr *p1;
	Tpr *p2;
	Tpr *t;
	Tpr *prior1;
	Tpr *prior2;

	for(pc = head; pc; pc = pc -> next)
	{
		for(pp = pc -> player; pp; pp = pp -> next)
		{
			pt = *pt_head;
			*pt_head = (Tpr *)malloc(sizeof(Tpr));
			strcpy((*pt_head) -> player, pp -> name);
			strcpy((*pt_head) -> clubname, pp -> clubname);
			(*pt_head) -> gamesum = pp -> gamesum;
			(*pt_head) -> win = pp -> victories;
			(*pt_head) -> lose = (*pt_head) -> gamesum - (*pt_head) -> win;
			(*pt_head) -> rate = (*pt_head) -> gamesum ? 
				((*pt_head) -> win / (*pt_head) -> gamesum) : 1;
			(*pt_head) -> next = pt;
		}
	}

	p1 = (Tpr *)malloc(sizeof(Tpr));
	p1 -> next = *pt_head;
	*pt_head = p1;
	for(prior1 = p1, p1 = prior1 -> next; p1 -> next; prior1 = p1, p1 = p1 -> next)
	{
		for(prior2 = p1, p2 = prior2 -> next; p2; prior2 = p2, p2 = p2 -> next)
		{
			if (p1 -> rate < p2 -> rate)
			{
				t = p2 -> next;
				prior1 -> next = p2;
				prior2 -> next = p1;
				p2 -> next = p1 -> next;
				p1 -> next = t;
				t = p1;
				p1 = p2;
				p2 = p1;
			}
		}	
	}
	p1 = *pt_head;
	*pt_head = p1 -> next;
	free(p1);
	p1 = NULL;

	return;
}


void run_rank_sum(GtkWidget *widget, gpointer data)
{
	if(check_before_ranking() != 2)
	{
		run_warning_dialog();
		return;
	}

	enum{
		COL_RANK = 0,
		COL_SUM,
		NUM_COLS
	};
	
	GtkCellRenderer *renderer;
	GtkTreeModel *model;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;

	int sum[9] = {0};
	int i;

	view = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));

	GList *list;
	GList *l;
	list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
	for(l = list; l; l = l -> next)
	{
		gtk_tree_view_remove_column(GTK_TREE_VIEW(view), l -> data);
	}
	g_list_free(list);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "段位",  
                                               renderer,
                                               "text", COL_RANK,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "人数",  
                                               renderer,
                                               "text", COL_SUM,
                                               NULL);

	store = gtk_list_store_new(NUM_COLS, G_TYPE_INT, G_TYPE_INT);

	rank_sum(&sum);
	for(i = 9; i > 0; i --)
	{
		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
						  	COL_RANK, i,
						  	COL_SUM, sum[i - 1],
	                  -1);
	}

	model = GTK_TREE_MODEL(store);
	gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
	g_object_unref (model);

	GtkBox *box = GTK_BOX(gtk_builder_get_object(builder, "box1"));
	gtk_box_pack_end(box, view, TRUE, TRUE, 0);
	
	gtk_widget_show(view);
}


static void rank_sum(int (*sum)[9])
{
	Club *pc;
	Player *pp;
	char rank;
	int i;

	for(pc = head; pc; pc = pc -> next)
	{
		for(pp = pc -> player; pp; pp = pp -> next)
		{
			rank = pp -> rank;
			switch(rank)
			{
				case '1': case '2': case '3': case '4':
				case '5': case '6': case '7': case '8':
				case '9':
					(*sum)[rank - '1'] ++;
					break; 
			}
		}
	}

	return;
}


void run_rank_ranking(GtkWidget *widget, gpointer data)
{
	if(check_before_ranking() != 2)
	{
		run_warning_dialog();
		return;
	}

	enum{
		COL_CLUB = 0,
		COL_PLAYER,
		COL_RANK,
		COL_GAMESUM,
		COL_VICTORIES,
		NUM_COLS
	};
	
	GtkCellRenderer *renderer;
	GtkTreeModel *model;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;

	Trr *pt_head = NULL;
	Trr *pt;

	view = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));

	GList *list;
	GList *l;
	list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
	for(l = list; l; l = l -> next)
	{
		gtk_tree_view_remove_column(GTK_TREE_VIEW(view), l -> data);
	}
	g_list_free(list);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "俱乐部",  
                                               renderer,
                                               "text", COL_CLUB,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "棋手",  
                                               renderer,
                                               "text", COL_PLAYER,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "段位",  
                                               renderer,
                                               "text", COL_RANK,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "总局数",  
                                               renderer,
                                               "text", COL_GAMESUM,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1, 
                                               "总胜场",
                                               renderer,
                                               "text", COL_VICTORIES,
                                               NULL);

	store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
		G_TYPE_INT, G_TYPE_INT);

	rank_ranking(&pt_head);
	for(pt = pt_head; pt; pt = pt -> next)
	{
		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
						  	COL_CLUB, pt -> clubname,
						  	COL_PLAYER, pt -> name,
						  	COL_RANK, pt -> rank - '0',
						  	COL_GAMESUM, pt -> gamesum,
						  	COL_VICTORIES, pt -> victories,
	                  -1);
	}

	model = GTK_TREE_MODEL(store);
	gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
	g_object_unref (model);

	GtkBox *box = GTK_BOX(gtk_builder_get_object(builder, "box1"));
	gtk_box_pack_end(box, view, TRUE, TRUE, 0);
	
	gtk_widget_show(view);
}


static void rank_ranking(Trr **pt_head)
{
	Club *pc;
	Player *pp;
	Trr *pt;
	Trr *p1;
	Trr *p2;
	Trr *t;
	Trr *prior1;
	Trr *prior2;

	for(pc = head; pc; pc = pc -> next)
	{
		for(pp = pc -> player; pp; pp = pp -> next)
		{
			pt = *pt_head;
			*pt_head = (Trr *)malloc(sizeof(Trr));
			strcpy((*pt_head) -> clubname, pp -> clubname);
			strcpy((*pt_head) -> name, pp -> name);
			(*pt_head) -> rank = pp -> rank;
			(*pt_head) -> gamesum = pp -> gamesum;
			(*pt_head) -> victories = pp -> victories;
			(*pt_head) -> next = pt;
		}
	}

	p1 = (Trr *)malloc(sizeof(Trr));
	p1 -> next = *pt_head;
	*pt_head = p1;
	for(prior1 = p1, p1 = prior1 -> next; p1 -> next; prior1 = p1, p1 = p1 -> next)
	{
		for(prior2 = p1, p2 = prior2 -> next; p2; prior2 = p2, p2 = p2 -> next)
		{
			if (p1 -> rank < p2 -> rank)
			{
				t = p2 -> next;
				prior1 -> next = p2;
				prior2 -> next = p1;
				p2 -> next = p1 -> next;
				p1 -> next = t;
				t = p1;
				p1 = p2;
				p2 = p1;
			}
		}	
	}
	p1 = *pt_head;
	*pt_head = p1 -> next;
	free(p1);
	p1 = NULL;

	return;
}


void run_club_info(GtkWidget *widget, gpointer data)
{
	if(!check_before_ranking())
	{
		return;
	}

	enum{
		COL_CLUB = 0,
		COL_PRIME,
		COL_FAST,
		COL_BLACK_SUM,
		COL_BLACK_VICTORIES,
		COL_WHITE_SUM,
		COL_WHITE_VICTORIES,
		NUM_COLS
	};
	
	GtkCellRenderer *renderer;
	GtkTreeModel *model;
	GtkWidget *view;
	GtkListStore *store;
	GtkTreeIter iter;

	Club *pc;
	Player *pp;
	Game *pg;
	char clubname[CLUBNAME_LEN];
	int prime_victories;
	int fast_victories;
	int blacksum;
	int black_victories;
	int whitesum;
	int white_victories;

	view = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));

	GList *list;
	GList *l;
	list = gtk_tree_view_get_columns(GTK_TREE_VIEW(view));
	for(l = list; l; l = l -> next)
	{
		gtk_tree_view_remove_column(GTK_TREE_VIEW(view), l -> data);
	}
	g_list_free(list);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "俱乐部",  
                                               renderer,
                                               "text", COL_CLUB,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "主将局胜",  
                                               renderer,
                                               "text", COL_PRIME,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "快棋局胜",  
                                               renderer,
                                               "text", COL_FAST,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "执黑",  
                                               renderer,
                                               "text", COL_BLACK_SUM,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "执黑胜",  
                                               renderer,
                                               "text", COL_BLACK_VICTORIES,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "执白",  
                                               renderer,
                                               "text", COL_WHITE_SUM,
                                               NULL);

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (view),
                                               -1,      
                                               "执白胜",  
                                               renderer,
                                               "text", COL_WHITE_VICTORIES,
                                               NULL);

	store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT,
		G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);

	for(pc = head; pc; pc = pc -> next)
	{
		strcpy(clubname, pc -> name);
		prime_victories = fast_victories = blacksum =
			black_victories = whitesum = white_victories = 0;
		for(pp = pc -> player; pp; pp = pp -> next)
		{
			for(pg = pp -> game; pg; pg = pg -> next)
			{
				if (get_winner(pg -> player -> name, 
					pg -> black, pg -> white, pg -> status))
				{
					switch(pg -> tag)
					{
						case '0':
							prime_victories ++;
							break;

						case '1':
							fast_victories ++;
							break;
					}
					if (!strcmp(pg -> player -> name, pg -> black))
					{
						black_victories ++;
					}
					else
					{
						white_victories ++;
					}
				}
				if (!strcmp(pg -> player -> name, pg -> black))
				{
					blacksum ++;
				}
				else
				{
					whitesum ++;
				}
			}
		}
		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
						  	COL_CLUB, clubname,
						  	COL_PRIME, prime_victories,
						  	COL_FAST, fast_victories,
						  	COL_BLACK_SUM, blacksum,
						  	COL_BLACK_VICTORIES, black_victories,
						  	COL_WHITE_SUM, whitesum,
						  	COL_WHITE_VICTORIES, white_victories,
	                  -1);
	}

	model = GTK_TREE_MODEL(store);
	gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
	g_object_unref (model);

	GtkBox *box = GTK_BOX(gtk_builder_get_object(builder, "box1"));
	gtk_box_pack_end(box, view, TRUE, TRUE, 0);
	
	gtk_widget_show(view);

	return;
}



void run_show_clubs(GtkWidget *widget, gpointer data)
{
	Club *pc = head;
	if(head)
	{
		fill_data_query_club("", 'a');	
	}
	else
	{
		run_warning_dialog();
	}

	return;
}


void run_show_all(GtkWidget *widget, gpointer data)
{
	show_all();
	return;
}


gboolean run_quit_dialog(GtkWidget *widget, 
						 GdkEvent *event,
						 gpointer data)
{
	GObject *dialog = gtk_builder_get_object(builder, "messagedialog2");
	gint result = gtk_dialog_run(GTK_DIALOG(dialog));

	switch(result)
	{
		case 1:
			debug("press cancle!");
			gtk_widget_hide(GTK_WIDGET(dialog));
			return TRUE;

		case 2:
			debug("press quit!");
			gtk_widget_hide(GTK_WIDGET(dialog));
			return FALSE;
	}
}